<script>
import {doDelete, doGet, doPost, doPut} from "../../http/httpRequest.js";
import {PAGE_SIZE} from "../../contants/constants.js";
import {msgConfirm, msgTip} from "../../util/util.js";

export default {
  name: "JobManagerView",
  inject:['reload'],
  data() {
    return {
      queryJob: {},
      groups: [],
      jobs: [],
      originalJob:{},
      job: {
        jobName: '',
        jobGroup: '',
        cronExpression: '',
        description: '',
        initStatus: 0 // 设置默认值
      },

      pageSize: PAGE_SIZE,
      total: 0,
      selectedRows: [],
      isAdd: false,
      initStatus:[{value: 0,label:'暂停'},{value: 1,label:'正常'}],
      jobDialogVisible: false,
      dialogTitle:"",
      triggerStatus: [
        {value: 'WAITING', label: '等待触发'},
        {value: 'ACQUIRED', label: '等待执行'},
        {value: 'EXECUTING', label: '正在执行'},
        {value: 'PAUSED', label: '暂停'},
        {value: 'BLOCKED', label: '阻塞'}
      ],
      jobRules: {
        jobGroup: [
          {required: true, message: '请选择Job分组', trigger: 'blur'},
          {validator: this.validateJobGroupAndJobName, trigger: 'blur'}
        ],
        jobName: [
          {required: true, message: '请输入Job名称', trigger: 'blur'},
          {validator: this.validateJobGroupAndJobName, trigger: 'blur'}
        ],
        jobClass: [
          {required: true, message: '请输入Job类名', trigger: 'blur'},
          {validator: this.validateJobClass, trigger: 'blur'}
        ],
        cronExpression: [
          {required: true, message: '请输入Cron表达式', trigger: 'blur'},
          {validator: this.validateCronExpression, trigger: 'blur'}
        ],
        initStatus: [
          {required: true, message: '请选择一个初始状态', trigger: 'blur'}
        ]
      },
      jobSubmit: {
        jobGroup: '',
        jobName: '',
        cronExpression: '',
        description: '',
        jobClass: '',
        initStatus: 0
      }

    }
  },
  methods: {
    getAllGroups() {
      doGet("/job/AllGroups").then(resp => {
        if (resp.data.code === 200) {
          this.groups = resp.data.data;
        }
      })
    },

    getJobsByGroup() {
      if (this.queryJob.jobGroup) {
        doGet("/job/getJobsByGroup", {jobGroup: this.queryJob.jobGroup}).then(resp => {
          if (resp.data.code === 200) {
            this.jobs = resp.data.data;
          }
        })
      } else {
        this.jobs = [];
      }
    },

    handleSelectionChange(selection) {
      this.selectedRows = selection.map(item => ({
            jobGroup: item.jobGroup,
            jobName: item.jobName
      }));
    },

    /* 修改页码时查询指定页数据 */
    handleCurrentChange(current) {
      this.getData(current);
    },

    /* 按条件分页查询数据 */
    getData(current) {
      const params = new URLSearchParams();
      params.append("page", current);
      params.append("jobGroup", this.queryJob.jobGroup || "");
      params.append("jobName", this.queryJob.jobName || "");
      params.append("description", this.queryJob.description || "");

      if(this.queryJob.triggerStatus && this.queryJob.triggerStatus.length > 0) {
        this.queryJob.triggerStatus.forEach(status => {
          params.append("triggerStatusList", status);
        });
      }

      doGet("/job/list", params).then(resp => {
        if (resp.data.code === 200) {
          this.jobs = resp.data.data.list;
          this.pageSize = resp.data.data.pageSize;
          this.total = resp.data.data.total;
        }
      })
    },

    /* 查询 */
    search() {
      this.getData(1);
    },
    /* 重置 */
    reset() {
      this.queryJob = {};
      this.getData(1);
    },

    /* 新增任务 */
    addJob() {
      this.jobDialogVisible = true;
      this.isAdd = true;
      this.job = {
        jobName: '',
        jobGroup: '',
        cronExpression: '',
        description: '',
        initStatus: 0 // 设置默认值
      };
      this.dialogTitle = "新增任务";
    },

    /* 恢复job任务执行 */
    resume(job) {
      msgConfirm("确定要恢复吗？").then(()=> {
        doPost("/job/resume",job ).then(resp => {
          if (resp.data.code === 200) {
            msgTip("恢复任务成功", "success");
            this.reload();
          } else {
            msgTip("恢复任务失败", "error");
          }
        })
      }).catch(() => {
        msgTip("取消了恢复", 'warning');
      })
    },

    /* 暂停job任务执行 */
    pause(job) {
      msgConfirm("确定要暂停吗？").then(()=> {
        doPost("/job/pause", job).then(resp => {
          if (resp.data.code === 200) {
            msgTip("暂停任务成功", "success");
            this.reload();
          } else {
            msgTip("暂停任务失败", "error");
          }
        })
     }).catch(() => {
        msgTip("取消了暂停", 'warning');
      })
    },

    /* 删除指定的定时任务 */
    del(jobGroup,jobName) {
      msgConfirm("确定要删除吗？").then(()=> {
        doDelete("/job/delete", {
          jobGroup: jobGroup,
          jobName: jobName
        }).then(resp => {
          if (resp.data.code === 200) {
            msgTip("删除任务成功", "success");
            this.reload();
          } else {
            msgTip("删除任务失败", "error");
          }
        })
      }).catch(() => {
        msgTip("取消了删除", 'warning');
      })
    },

    /* 手动触发一起任务 */
    trigger(jobGroup,jobName) {
      msgConfirm("确定要手动触发吗？").then(()=> {
        doPost("/job/trigger", {
          jobGroup: jobGroup,
          jobName: jobName
        }).then(resp => {
          if (resp.data.code === 200) {
            msgTip("手动触发任务成功", "success");
            this.reload();
          } else {
            msgTip("手动触发任务失败", "error");
          }
        })
      }).catch(() => {
        msgTip("取消了手动触发", 'warning');
      })
    },

    /* 编辑 */
    edit(jobGroup,jobName) {
      doGet("/job/getByGroupNameAndJobName", {
        jobGroup: jobGroup,
        jobName: jobName
      }).then(resp => {
        if (resp.data.code === 200) {
          this.jobDialogVisible = true;
          this.isAdd = false;
          this.job = resp.data.data;
          this.dialogTitle = "编辑任务";
          this.job.initStatus = 0;
          this.originalJob = {...resp.data.data};
        } else {
          msgTip("获取任务失败", "error");
        }
      })
    },


    /* 提交新增或编辑 */
    jobDialogSubmit() {
      this.$refs.jobDialogRefForm.validate(valid => {
        if (valid) {
          if(this.isAdd) {
            // 新增
            doPost("/job/add", this.job).then(resp => {
              if(resp.data.code === 200) {
                // 新增成功
                msgTip("新增Job任务成功","success");
                this.reload();
              } else {
                msgTip("新增Job任务失败","error");
              }
            });
          } else {
            // 编辑
            doPut("/job/update", this.job).then(resp => {
              if (resp.data.code === 200){
                msgTip("编辑Job任务成功","success");
                this.reload();
              } else {
                msgTip("编辑Job任务失败","error");
              }
            });
          }
        }
      })
    },

    /* 批量删除 */
    batchDelJob() {
      msgConfirm("确定要删除吗？").then(()=> {
        doPost("/job/batchDelete", this.selectedRows).then(resp => {
          if(resp.data.code === 200) {
            msgTip("删除成功","success");
            this.reload();
          } else {
            msgTip("删除失败","error");
          }
        })
      }).catch(() => {
        msgTip("取消了删除", 'warning');
      })
    },


    /* 对话框校验 */
    validateJobGroupAndJobName(rule, value, callback) {
      if(this.isAdd) {
        // 新增任务
        doGet("/job/checkJobGroupAndJobName", {
          jobGroup: this.job.jobGroup,
          jobName: this.job.jobName
        }).then(resp => {
          if(resp.data.data) {
            callback(new Error("同一分组下任务名不允许重复！"));
          } else {
            callback();
          }
        })
      } else {
        if(this.job.jobGroup !== this.originalJob.jobGroup || this.job.jobName !== this.originalJob.jobName) {
          doGet("/job/checkJobGroupAndJobName", {
            jobGroup: this.job.jobGroup,
            jobName: this.job.jobName
          }).then(resp => {
            if(resp.data.data) {
              callback(new Error("同一分组下任务名不允许重复！"));
            } else {
              callback();
            }
          })
        } else {
          callback();
        }
      }
    },

    validateJobClass(rule, value, callback) {
      doGet("/job/checkJobClassName", {
        jobClass: this.job.jobClass
        }).then(resp => {
          if(!resp.data.data) {
            callback(new Error("提供的类名并非任务类"));
          } else {
            callback();
          }
      })
    },

    validateCronExpression(rule, value, callback) {
      doGet("/job/checkCronExpression", {
        cronExpression: this.job.cronExpression
      }).then(resp => {
        if(!resp.data.data) {
          callback(new Error("提供的Cron表达式无效"));
        } else {
          callback();
        }
      })
    }

  },
  mounted() {
    this.getAllGroups();
    this.getData(1);
  }
}
</script>

<template>
  <!-- 查询区域 -->
  <el-form :inline="true" :model="queryJob" class="query-form">
    <el-form-item label="Job分组">
      <el-select v-model="queryJob.jobGroup" placeholder="请选择分组" clearable filterable @change="getJobsByGroup">
        <el-option
          v-for="group in groups"
          :key="group.jobGroup"
          :label="group.jobGroup"
          :value="group.jobGroup"
        />
      </el-select>
    </el-form-item>
    <el-form-item label="Job">
      <el-select v-model="queryJob.jobName" placeholder="请选择Job" clearable filterable>
        <el-option
          v-for="job in jobs"
          :key="job.jobName"
          :label="job.jobName"
          :value="job.jobName"
        />
      </el-select>
    </el-form-item>
    <el-form-item label="触发器状态">
      <el-select v-model="queryJob.triggerStatus" placeholder="请选择触发器状态" clearable filterable multiple>
        <el-option
          v-for="item in triggerStatus"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
    </el-form-item>
    <el-form-item label="Job描述">
      <el-input v-model="queryJob.description" placeholder="请输入job描述" clearable />
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="search">查询</el-button>
      <el-button type="info" @click="reset">重置</el-button>
    </el-form-item>
  </el-form>
  <el-divider/>

  <div class="op-btn">
    <el-button type="primary" class="btn" @click="addJob">新增任务</el-button>
    <el-button type="danger" class="btn" @click="batchDelJob">批量删除</el-button>
  </div>

  <!-- 列表 -->
  <el-table
      :data="jobs"
      style="width:100%"
      @selection-change="handleSelectionChange"
      class="custom-table"
      border
      stripe>
    <el-table-column type="selection" width="50"/>
    <el-table-column type="index" label="序号" width="80"/>
    <el-table-column prop="jobGroup" label="Job分组"/>
    <el-table-column prop="jobName" label="Job名称"/>
    <el-table-column prop="description" label="Job描述" />
    <el-table-column prop="jobClass" label="Job类名" />
    <el-table-column prop="triggerStatus" label="触发器状态" >
      <template #default="scope">
        <el-tag v-if="scope.row.triggerStatus === 'WAITING'" type="success">等待触发</el-tag>
        <el-tag v-if="scope.row.triggerStatus === 'ACQUIRED'" type="success">等待执行</el-tag>
        <el-tag v-if="scope.row.triggerStatus === 'EXECUTING'" type="success">正在执行</el-tag>
        <el-tag v-if="scope.row.triggerStatus === 'PAUSED'" type="warning">暂停</el-tag>
        <el-tag v-if="scope.row.triggerStatus === 'BLOCKED'" type="danger">阻塞</el-tag>
      </template>
    </el-table-column>
    <el-table-column prop="cronExpression" label="Cron表达式" />
    <el-table-column prop="previousFireTime" label="上次触发时间" />
    <el-table-column prop="nextFireTime" label="下次触发时间" />
    <el-table-column label="操作">
      <template #default="scope">
        <div class="button-column">
          <el-button type="success" @click="edit(scope.row.jobGroup,scope.row.jobName)" size="small">编辑</el-button>
          <el-button v-if="scope.row.triggerStatus === 'PAUSED'" type="primary" @click="resume(scope.row)" size="small">恢复</el-button>
          <el-button v-else type="warning" @click="pause(scope.row)" size="small">暂停</el-button>
          <el-button type="danger" @click="del(scope.row.jobGroup, scope.row.jobName)" size="small">删除</el-button>
          <el-button type="info" @click="trigger(scope.row.jobGroup, scope.row.jobName)" size="small">执行一次</el-button>
        </div>
        </template>
    </el-table-column>
  </el-table>
  <el-pagination background
                 layout="prev, pager, next, jumper, total"
                 :page-size="pageSize"
                 :total="total"
                 @current-change="handleCurrentChange"
                 class="pagination" />

 <!-- 新增编辑对话框 -->
  <el-dialog v-model="jobDialogVisible" :title="dialogTitle" width="40%" :close-on-click-modal="false">
    <el-form ref="jobDialogRefForm" :model="job" label-width="110px" :rules="jobRules">
      <el-form-item label="Job分组" prop="jobGroup">
        <el-input v-model="job.jobGroup" clearable />
      </el-form-item>
      <el-form-item label="Job名称" prop="jobName">
        <el-input v-model="job.jobName" clearable />
      </el-form-item>
      <el-form-item label="Job类名" prop="jobClass">
        <el-input v-model="job.jobClass" clearable />
      </el-form-item>
      <el-form-item label="Cron表达式" prop="cronExpression">
        <el-input v-model="job.cronExpression" clearable />
      </el-form-item>
      <!-- <el-form-item label="初始状态" v-if="isAdd">-->
      <el-form-item label="初始状态" >
        <el-select v-model="job.initStatus" placeholder="请选择初始状态" clearable filterable>
          <el-option
              v-for="status in initStatus"
              :key="status.value"
              :label="status.label"
              :value="status.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="Job描述" prop="description">
        <el-input v-model="job.description" clearable />
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="jobDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="jobDialogSubmit">确 定</el-button>
      </span>
    </template>
  </el-dialog>

</template>

<style scoped>
.query-form {
  .el-input {
    width: 220px;
  }
  .el-select {
    width: 220px;
  }
}

.op-btn {
  margin-top: 20px;
  display: flex;
  justify-content: flex-start;
}

.custom-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 20px;
}
.custom-table ::v-deep th {
  background-color: rgb(190, 190, 190) ; /* 背景色 */
  color: #303133;
  font-weight: bold; /* 加粗字体 */
 }

.custom-table ::v-deep th,
.custom-table ::v-deep td {
  padding: 10px;
  text-align: left;
}


.custom-table ::v-deep tr:nth-child(even) {
  background-color: #f9f9f9;
}

.custom-table ::v-deep tr:hover {
  background-color: #f1f1f1;
}


.pagination {
  margin-top: 20px;
}

.button-column {
  display: flex;
  flex-direction: column;
  gap: 5px; /* 设置按钮之间的间距 */
  .el-button {
    width: 80px;
    margin-left: 0 !important;
  }
}
</style>